package com.nbsaas.boot.plugin.file;

import com.nbsaas.boot.plugin.Plugin;
import com.nbsaas.boot.plugin.PluginContext;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 文件上传插件
 * 支持多种文件上传方式和格式验证
 */
public class FileUploadPlugin implements Plugin {
    private PluginContext context;
    private Path uploadDir;
    private final Map<String, Set<String>> allowedExtensions = new ConcurrentHashMap<>();
    private final Map<String, Long> maxFileSizes = new ConcurrentHashMap<>();
    
    @Override
    public String getId() {
        return "file-upload-plugin";
    }
    
    @Override
    public String getName() {
        return "文件上传插件";
    }
    
    @Override
    public String getVersion() {
        return "1.0.0";
    }
    
    @Override
    public String getDescription() {
        return "提供文件上传、格式验证、大小限制等功能";
    }
    
    @Override
    public void init(PluginContext context) {
        this.context = context;
        System.out.println("文件上传插件初始化: " + getName());
        
        // 创建上传目录
        uploadDir = Paths.get(System.getProperty("java.io.tmpdir"), "uploads");
        try {
            Files.createDirectories(uploadDir);
        } catch (IOException e) {
            System.err.println("创建上传目录失败: " + e.getMessage());
        }
        
        // 初始化允许的文件类型
        initAllowedExtensions();
        // 初始化文件大小限制
        initMaxFileSizes();
    }
    
    private void initAllowedExtensions() {
        // 图片类型
        allowedExtensions.put("image", new HashSet<>(Arrays.asList(
            "jpg", "jpeg", "png", "gif", "bmp"
        )));
        
        // 文档类型
        allowedExtensions.put("document", new HashSet<>(Arrays.asList(
            "pdf", "doc", "docx", "xls", "xlsx", "txt"
        )));
        
        // 视频类型
        allowedExtensions.put("video", new HashSet<>(Arrays.asList(
            "mp4", "avi", "mov", "wmv"
        )));
    }
    
    private void initMaxFileSizes() {
        // 设置不同类型文件的大小限制（单位：字节）
        maxFileSizes.put("image", 10L * 1024 * 1024);      // 10MB
        maxFileSizes.put("document", 50L * 1024 * 1024);   // 50MB
        maxFileSizes.put("video", 500L * 1024 * 1024);     // 500MB
    }
    
    @Override
    public void start() {
        System.out.println("文件上传插件启动: " + getName());
    }
    
    @Override
    public void stop() {
        System.out.println("文件上传插件停止: " + getName());
    }
    
    /**
     * 上传文件
     * @param file 要上传的文件
     * @param type 文件类型（image/document/video）
     * @return 上传结果
     */
    public UploadResult uploadFile(File file, String type) {
        if (file == null || !file.exists()) {
            return UploadResult.error("文件不存在");
        }
        
        // 验证文件类型
        String extension = getFileExtension(file.getName());
        if (!isAllowedExtension(extension, type)) {
            return UploadResult.error("不支持的文件类型: " + extension);
        }
        
        // 验证文件大小
        if (!isValidFileSize(file.length(), type)) {
            return UploadResult.error("文件大小超过限制");
        }
        
        try {
            // 生成唯一文件名
            String newFileName = UUID.randomUUID().toString() + "." + extension;
            Path targetPath = uploadDir.resolve(newFileName);
            
            // 复制文件
            Files.copy(file.toPath(), targetPath);
            
            return UploadResult.success(newFileName, targetPath.toString());
        } catch (IOException e) {
            return UploadResult.error("文件上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 删除已上传的文件
     * @param fileName 文件名
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileName) {
        try {
            Path filePath = uploadDir.resolve(fileName);
            return Files.deleteIfExists(filePath);
        } catch (IOException e) {
            System.err.println("删除文件失败: " + e.getMessage());
            return false;
        }
    }
    
    private String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        return (dotIndex == -1) ? "" : fileName.substring(dotIndex + 1).toLowerCase();
    }
    
    private boolean isAllowedExtension(String extension, String type) {
        Set<String> allowed = allowedExtensions.get(type);
        return allowed != null && allowed.contains(extension.toLowerCase());
    }
    
    private boolean isValidFileSize(long fileSize, String type) {
        Long maxSize = maxFileSizes.get(type);
        return maxSize != null && fileSize <= maxSize;
    }
    
    /**
     * 上传结果类
     */
    public static class UploadResult {
        private final boolean success;
        private final String fileName;
        private final String filePath;
        private final String error;
        
        private UploadResult(boolean success, String fileName, String filePath, String error) {
            this.success = success;
            this.fileName = fileName;
            this.filePath = filePath;
            this.error = error;
        }
        
        public static UploadResult success(String fileName, String filePath) {
            return new UploadResult(true, fileName, filePath, null);
        }
        
        public static UploadResult error(String error) {
            return new UploadResult(false, null, null, error);
        }
        
        public boolean isSuccess() {
            return success;
        }
        
        public String getFileName() {
            return fileName;
        }
        
        public String getFilePath() {
            return filePath;
        }
        
        public String getError() {
            return error;
        }
    }
} 